﻿#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

//int main()
//{
//	int a = 10;
//	int b = a << 1;
//	printf("%d\n", a);
//	printf("%d\n", b); //20
//	return 0;
//}
	//a --> 00000000000000000000000000001010
	//b --> 00000000000000000000000000001010
    //b --> 00000000000000000000000000010100
	//因为正整数的原、反、补一样所以可以直接左移一位，然后在末尾补0
	//由于前面都是0使用取后五位   10100
	//2进制转10进制就是  1*2^4 + 0*2^3 + 1*2^2 + 0*2^1 + 0*2^0
	//					 16      0       4        0      0
	//结果就是20

//int main()
//{
//	int a = -10;
//	int b = a << 1;
//	printf("%d\n", a);
//	printf("%d\n", b); //-20
//	return 0;
//}
//		a --> 10000000000000000000000000001010
//因为是负整数原码、反码、补码不相同因此要得到补码才能运算
//b原码	  --> 10000000000000000000000000001010   
//b反码	  --> 11111111111111111111111111110101  原码取反
//b补码	  --> 11111111111111111111111111110110  补码+1
//a << 1  --> 11111111111111111111111111101100
// 转换回去
//			  10000000000000000000000000010011  取反
//			  10000000000000000000000000010100  +1
//符号位是1因此是负数，再取10100转换成10进制
//2进制转10进制就是  1*2^4 + 0*2^3 + 1*2^2 + 0*2^1 + 0*2^0
//					 16      0       4        0      0
//结果就是-20

//int main()
//{
//	int a = 10;
//	int b = a >> 1;
//	printf("%d\n", a);
//	printf("%d\n", b); //
//	return 0;
//}
	//算术右移：
	//a --> 00000000000000000000000000001010
	//b --> 00000000000000000000000000001010
	//b --> 00000000000000000000000000000101
	//因为正整数的原、反、补一样所以可以直接右移一位，然后在高位补原符号位
	//由于前面都是0所以取后三位   101
	//2进制转10进制就是   1*2^2 + 0*2^1 + 1*2^0
	//					  4       0       1
	//结果就是5

//int main()
//{
//	int a = -10;
//	int b = a >> 1;
//	printf("%d\n", a);
//	printf("%d\n", b); //
//	return 0;
//}
	//逻辑右移：
	//a --> 10000000000000000000000000001010
	//b --> 10000000000000000000000000001010
	//b --> 11111111111111111111111111110101 取反
	//b --> 11111111111111111111111111110110 +1
	//a >> 1 --> 01111111111111111111111111111011
	// 逻辑右移1位，然后高位补0
	//b -->01111111111111111111111111111011
	//因为符号位是0所以是正整数其原、反、补一样
	//取1111111111111111111111111111011

//int main()
//{
//	int a = 3;  //00000000000000000000000000000011
//	int b = -5; //10000000000000000000000000000101 原码
//	            //11111111111111111111111111111010 取反
//	
//	//b补码		  11111111111111111111111111111011
//	//a补码		  00000000000000000000000000000011
//	printf("%d\n", a & b); //相同为1则为1，否则为0
//				//00000000000000000000000000000011
//				//3
//	
//	printf("%d\n", a | b); //相同为0则为0，否则为1
//				//11111111111111111111111111111011		
//				//10000000000000000000000000000100 取反
//				//10000000000000000000000000000101 +1得原码
//				//-5
//	
//	printf("%d\n", a ^ b); ////相同为0，不同为1
//				//11111111111111111111111111111000
//				//10000000000000000000000000000111 取反
//				//10000000000000000000000000001000 +1得原码
//				//-8
//	
//	printf("%d\n", ~0); //对应位为0，结果位为1；对应位为1，结果位为0；
//				//00000000000000000000000000000000
//			    //11111111111111111111111111111111
//			    //10000000000000000000000000000000 取反
//				//10000000000000000000000000000001 +1得原码
//				//-1
//	return 0;
//}

//不能创建临时变量（第三个变量），实现两个数的交换。
//int main()
//{
//	int a = 10; //00000000000000000000000000001010
//	int b = 20; //00000000000000000000000000010100
//
//	a = a ^ b;  //00000000000000000000000000011110
//	printf("%d\n", a); //30
//	b = a ^ b;  //00000000000000000000000000001010
//
//	a = a ^ b;  //00000000000000000000000000010100
//	printf("a=%d,b=%d\n", a, b);
//	return 0;
//}

//求⼀个整数存储在内存中的⼆进制中1的个数
//int main()
//{
//	int a = -1;
//	int i = 0;
//	int count = 0;
//	for (i = 0; i < 32; i++)
//	{
//		if (a & (1 << i))
//		{
//			//11111111111111111111111111111111111 -1
//			//00000000 00000000 00000000 00000001 1 << i -> 0
//			//00000000 00000000 00000000 00000001 a & (1 << i)
//			
//			//00000000 00000000 00000000 00000010 1 << i -> 1
//			//00000000 00000000 00000000 00000100 a & (1 << i)
//			count++;
//		}
//	}
//	printf("%d", count);
//	return 0;
//}


//将13⼆进制序列的第5位修改为1，然后再改回0
//int main()
//{
//	int a = 13;
//	a = a | (1 << 4);
//	//00000000000000000000000000001101  13
//	//00000000000000000000000000000001  1
//	//00000000000000000000000000010000  1 << 4
//	//00000000000000000000000000011101  a | (1 << 4)
//	printf("%d\n", a);
//	a = a & ~(1 << 4);
//	//00000000000000000000000000010000  1 << 4
//	//11111111111111111111111111101111  ~(1 << 4)
//	//00000000000000000000000000011101  a 
//	//00000000000000000000000000001101
//	printf("%d\n", a);
//	return 0;
//}

//int main()
//{
//	int a = 1;
//	int b = 3;
//	int c = (a++, b--, b = a + b, a=a+b);
//	printf("%d", c);  //输出的是a=a+b的结果
//	if (a = a + b - 1, c = a / 2, b < 0)
//	{
//		printf("hello"); //不会打印
//	}
//	return 0;
//}

//int main()
//{
//	int arr[10];
//	arr[9] = 10;
//	printf("%d", arr[9]);
//	return 0;
//}



//void test1()
//{
//	printf("hello\n");
//}
//
//void test2(char * s)
//{
//	printf("%s\n", s);
//}
//int main()
//{
//	test1();             //这里的()就是作为函数调用操作符
//	test2("hello,C");    //这里的()就是函数调用操作符
//	return 0;
//}

//struct Stu    //类型声明
//{
//	char name[20];
//	int age;
//	char sex[10];
//	char s_id[20];
//}s2;  //声明类型的同时定义变量s2
//
//struct Point
//{
//	int x;
//	int y;
//};
//struct Node
//{
//	int date;
//	struct Point p;
//	struct Node* next;
//}n1 = { 10,{5,6},NULL };  //结构体嵌套初始化
//
//int main()
//{
//	struct Stu s1; //定义结构体变量s1
//	struct Stu s1 = { "zhangsan" , 20,  "female" , "110408" };  //初始化
//	struct Stu s2 = { .age = 20,.name = "lisi",.sex = "male",.s_id = "220408" };  //指定顺序初始化
//	return 0;
//}


//struct Point
//{
//	int x;
//	int y;
//}p1 = {6,8};
//
//int main()
//{
//	printf("x->%d y->%d\n", p1.x, p1.y); //结构体变量.成员名
//	struct Point p2 = { 3,4 };
//	struct Point* ptr = &p2;
//	ptr->x = 10;  //结构体指针->成员名
//	ptr->y = 20;
//	printf("x->%d y->%d\n", ptr->x, ptr->y);
//	return 0;
//}

//int main()
//{
//	char c1 = -1;
//	//char是 1 字节（8 位）
//	//11111111 因为char是有符号的char，
//	//所以整型提升的时候，高位补充符号位，即1
//	//提升之后的结果是11111111111111111111111111111111
//	char c2 = 1;
//	//00000001
//	//提升之后的结果是00000000000000000000000000000001
//}

//算术转换
int main()
{
	int a = 3;
	double b = 3.14;
	printf("%.3lf\n", a + b);
	//看似是非常简单的加法运算，其实编译器处理了int a
	//的转换3->3.0 成为double类型，然后再进行运算
	//也就是3.0(double)+3.14(double)=6.14(double)
	return 0;
}

